package gui;

import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.RoundRectangle2D;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Iterator;

import javax.swing.*;

import staticClasses.F;
import staticClasses.IP;
import staticClasses.Port;
import Projektarbete.*;

/**
 * 
 * @author Johan, Victor, August
 */

/*
 * New changes made by August 26-04-12. Remade class!
 */

public class MainFrame extends JFrame {

	private ImagePanel mainPanel;
	private JPanel grpPanel;
	private JPanel chatPanel;
	private JLabel exitButton;
	private JTabbedPane groupsTabbedPane;
	private JTabbedPane chatWindowTabbedPane;
	private JTabbedPane groupPane;
	private JTabbedPane chatPane;
	private ContactPanel kontakt;
	private GroupPanel group;
	private User user;
	private Point point;
	private ChatMemberPanel chatMemPanel;
	private SettingsPanel setting;
	private ArrayList<Friend> contactList = new ArrayList<Friend>();
	private ArrayList<ChatWindow> chatWindowList = new ArrayList<ChatWindow>();
	private ArrayList<ChatWindow> groupWindowList = new ArrayList<ChatWindow>();
	private ArrayList<StickyNotePanel> stickyNoteList = new ArrayList<StickyNotePanel>();
	private int chatID = 0;

	public MainFrame(User user) {
		this.user = user;
		new Thread(new ContactTabListFiller.ClientThread(this)).start();
		initComponents();
		// Starta chattréŒ®en.
		new Thread(new incomingChatThread()).start();
	}

	private void initComponents() {

		setUndecorated(true);
		mainPanel = new ImagePanel("src/BAKRUND.jpg");
		mainPanel.setBackground(new Color(5, 100, 98));
		groupsTabbedPane = new JTabbedPane();
		chatWindowTabbedPane = new JTabbedPane();
		point = new Point();
		chatWindowTabbedPane.setTabPlacement(JTabbedPane.BOTTOM);
		exitButton = new JLabel();
		ArrayList<User> userList = new ArrayList<User>();
		kontakt = new ContactPanel(this);
		group = new GroupPanel(this);
		setting = new SettingsPanel();
		
		Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
		int X = (screen.width / 2) - 430;
		int Y = (screen.height / 2) - 310;
		setBounds(X, Y, WIDTH, HEIGHT);

		addTogroupsTabbedPane("Contacts", kontakt);
		addTogroupsTabbedPane("Groups", group);
		addTochatWindowTabbedPane("Settings", setting);

		exitButton.setIcon(new ImageIcon("src/quit.png")); // NOI18N
		exitButton.addMouseListener(new java.awt.event.MouseAdapter() {
			public void mouseClicked(java.awt.event.MouseEvent evt) {
				shutDown(evt);
			}

			private void shutDown(MouseEvent evt) {
				userLogOff();
				dispose();
				System.exit(0);
			}

			public void mouseEntered(java.awt.event.MouseEvent evt) {
				mouseOver(evt);
			}

			private void mouseOver(MouseEvent evt) {
				exitButton
						.setIcon(new javax.swing.ImageIcon("src/quitOver.png"));

			}

			public void mouseExited(java.awt.event.MouseEvent evt) {
				mouseNotOver(evt);
			}

			private void mouseNotOver(MouseEvent evt) {
				exitButton.setIcon(new javax.swing.ImageIcon("src/quit.png"));

			}

			public void mousePressed(java.awt.event.MouseEvent evt) {
				pressQuit(evt);
			}

			private void pressQuit(MouseEvent evt) {
				exitButton.setIcon(new javax.swing.ImageIcon(
						"src/quitPressed.png"));

			}

			public void mouseReleased(java.awt.event.MouseEvent evt) {
				mouseOver(evt);
			}

		});

		javax.swing.GroupLayout mainPanelLayout = new javax.swing.GroupLayout(mainPanel);
        mainPanel.setLayout(mainPanelLayout);
        mainPanelLayout.setHorizontalGroup(
            mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, mainPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(mainPanelLayout.createSequentialGroup()
                        .addGap(0, 0, Short.MAX_VALUE)
                        .addComponent(exitButton))
                    .addGroup(mainPanelLayout.createSequentialGroup()
                        .addComponent(groupsTabbedPane, javax.swing.GroupLayout.PREFERRED_SIZE, 241, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(chatWindowTabbedPane, javax.swing.GroupLayout.DEFAULT_SIZE, 644, Short.MAX_VALUE)))
                .addGap(22, 22, 22))
        );
        mainPanelLayout.setVerticalGroup(
            mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(mainPanelLayout.createSequentialGroup()
                .addComponent(exitButton)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(groupsTabbedPane, javax.swing.GroupLayout.DEFAULT_SIZE, 569, Short.MAX_VALUE)
                    .addComponent(chatWindowTabbedPane))
                .addContainerGap())
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(mainPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addComponent(mainPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
        );

		addMouseListener(new MouseAdapter() {
			public void mousePressed(MouseEvent e) {
				point.x = e.getX();
				point.y = e.getY();
			}
		});
		addMouseMotionListener(new MouseMotionAdapter() {
			public void mouseDragged(MouseEvent e) {
				Point p = getLocation();
				setLocation(p.x + e.getX() - point.x, p.y + e.getY() - point.y);
			}
		});
		
		java.awt.Window wind = new java.awt.Window(this);
		Shape shape = null;
		shape = new RoundRectangle2D.Double(0, 0, getWidth(),
				getHeight(), 25, 25);
		//wind.getOwner().setShape(shape);
		pack();
		this.setVisible(true);
	}

	public void closeChatTab(int chat_id, boolean isGroup) {
		System.out.println("Chat id: " + chat_id);
		try {
			ObjectOutputStream out = new ObjectOutputStream(new Socket(
					IP.getServerIP(), Port.getServerPort()).getOutputStream());
			out.writeObject(F.USER_LEAVING_CHAT);
			out.writeObject(chat_id);
			out.writeObject(this.getUser());

			// Testing remove chatwindow.

			if (isGroup) {
				for (int i = 0; i < groupWindowList.size(); i++) {
					if (groupWindowList.get(i).getId() == chat_id) {
						groupWindowList.remove(i);
					}
				}
				stickyNoteList.remove(getStickyNoteWithId(chat_id));
			} else {
				for (int i = 0; i < chatWindowList.size(); i++) {
					if (chatWindowList.get(i).getId() == chat_id) {
						chatWindowList.remove(i);
					}
				}
			}

			out.close();
		} catch (UnknownHostException e1) {
			e1.printStackTrace();
		} catch (IOException e1) {
			e1.printStackTrace();
		}
	}

	/*
	 * Dessa Metoder lé‹‘ger till Tabs i de olika jTabbedPanel (de lé‹‘gs till i
	 * en tab med namnet "title")
	 */
	// Denna metod lé‹‘ger till GroupTaben och KontaktTaben
	public void addTogroupsTabbedPane(String title, Component component) {
		groupsTabbedPane.addTab(title, component);

	}

	// Denna metod lé‹‘ger till Panelenrna i tabs fé°Ž innehéŒ¶let i grupp och
	// kontakt flikarna
	public void addTochatWindowTabbedPane(String title, Component component) {
		chatWindowTabbedPane.addTab(title, component);
	}

	public void addGroup(Group group) {

		if (groupOpen(group.getId())) {
			groupPane = new JTabbedPane();
			grpPanel = new JPanel();
			grpPanel.setOpaque(false);
			GroupLayout groupPanelLayout = new GroupLayout(grpPanel);
			ChatMemberPanel groupMemPanel = new ChatMemberPanel(
					group.getMembers(), true);
			ChatWindow newWindow = new ChatWindow(user.getUserName(),
					group.getId(), group.getMembers(), groupMemPanel, true);
			FTPgui newFolder = new FTPgui(group, group.getName(),
					group.getId(), user);
			StickyNotePanel sp = new StickyNotePanel(group.getId());

			GroupLayout grpPanelLayout = new GroupLayout(grpPanel);
			groupMemPanel.setBackground(Color.white);
			grpPanel.setBackground(Color.white);

			setChatLayout(grpPanel, groupPane, groupMemPanel, groupPanelLayout);

			groupPane.add("Chat", newWindow);
			groupPane.add("Folder", newFolder);
			groupPane.add("History", sp);
			groupPane.add("Settings", new GroupSettings(group, user, this));
			groupWindowList.add(newWindow);
			stickyNoteList.add(sp);
			new TabbedPanePanel(chatWindowTabbedPane, group.getName(),
					grpPanel, this, group.getId(), newWindow.isGroup());
			chatWindowTabbedPane.setSelectedIndex(chatWindowTabbedPane
					.getComponentCount() - 2);
		}
	}

	public void addChat(ArrayList<User> userList, int chat_id) {

		if (chatOpen(chat_id)) {
			chatPane = new JTabbedPane();
			chatPanel = new JPanel();
			User user = getUser();
			GroupLayout chatPanelLayout = new GroupLayout(chatPanel);

			chatMemPanel = new ChatMemberPanel(userList);
			chatMemPanel.setBackground(Color.white);
			chatPanel.setBackground(Color.white);
			chatMemPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
			setChatLayout(chatPanel, chatPane, chatMemPanel, chatPanelLayout);

			ChatWindow chat;
			String str = "";

			for (int i = 0; i < userList.size(); i++) {

				if (str.equals("")
						&& !userList.get(i).getUserName()
								.equals(user.getUserName()))
					str += userList.get(i).getUserName();
				else if (i < userList.size()
						&& !userList.get(i).getUserName()
								.equals(user.getUserName()))
					str += ", " + userList.get(i).getUserName();
			}

			chat = new ChatWindow(user.getUserName(), chat_id, userList,
					chatMemPanel);
			chatWindowList.add(chat);
			chatPane.add("Chat", chat);

			new TabbedPanePanel(chatWindowTabbedPane, str, chatPanel, this,
					chat_id, chat.isGroup());
			chatWindowTabbedPane.setSelectedIndex(chatWindowTabbedPane
					.getComponentCount() - 2);
		}
	}

	public boolean chatOpen(int chat_id) {
		for (int i = 0; i < chatWindowList.size(); i++) {
			if (chatWindowList.get(i).getId() == chat_id) {
				return false;
			}
		}
		return true;
	}

	public boolean groupOpen(int group_id) {
		for (int i = 0; i < groupWindowList.size(); i++) {
			if (groupWindowList.get(i).getId() == group_id) {
				return false;
			}
		}
		return true;
	}

	public void sendChat(ArrayList<Contact> contactList) {
		Iterator<Contact> iterator = contactList.iterator();

		ArrayList<User> userArray = new ArrayList<User>();

		while (iterator.hasNext()) {
			Contact nextContact = iterator.next();
			if (nextContact.isChecked()) {

				userArray.add(nextContact.getUser());

			}

		}
		userArray.add(this.getUser());
		try {
			ObjectOutputStream out = new ObjectOutputStream(new Socket(
					IP.getServerIP(), Port.getServerPort()).getOutputStream());
			// Skickar singelchattrequest till chattserver.

			out.writeObject(F.START_CHAT);
			out.writeObject(userArray);

			out.close();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public StickyNotePanel getStickyNoteWithId(int groupId) {
		System.out.print("Searching for matching stickynote with id: "
				+ groupId + " .");
		for (int i = 0; i < stickyNoteList.size(); i++) {
			System.out.print(".");
			if (stickyNoteList.get(i).getGroupId() == groupId) {
				System.out.println("");
				System.out.println("Sticky Note Found with id: " + groupId);
				return stickyNoteList.get(i);
			}
		}
		System.out.println("Not found");
		return null;
	}

	public User getUser() {
		return user;
	}

	public MainFrame getMainFrame() {
		return this;
	}

	// Skickar user till servern med onlinestatus som false.
	public void userLogOff() {
		new ContactTabListFiller().userLogOff(user);
	}

	public void addSingleContact(User user) {
		kontakt.addSingleContact(user);
	}

	public void removeSingleContact(User user) {
		kontakt.removeSingleContact(user);
	}

	// Skapa tréŒ® som lyssnar pï¿½incoming chats.
	class incomingChatThread extends Thread {
		@SuppressWarnings("unchecked")
		public void run() {
			ArrayList<Object> objectList;
			ArrayList<User> userList;
			ServerSocket socket = null;
			Socket incomingChat = null;
			ObjectInputStream in;
			int functionID;
			String message;
			User userFromChat;
			final int START_GROUP_CHAT_FUNCTION_ID = 0;
			final int START_CHAT_FUNCTION_ID = 1;
			final int SEND_MESSAGE_FUNCTION_ID = 2;
			final int REMOVE_FROM_CHAT_FUNCTION_ID = 3;

			while (true) {

				System.out.println("Vi är i tråden.");
				try {
					socket = new ServerSocket(Port.getClientChatPort());
					incomingChat = socket.accept();
					in = new ObjectInputStream(incomingChat.getInputStream());

					functionID = (Integer) in.readObject();
					chatID = (Integer) in.readObject();

					if (functionID == START_GROUP_CHAT_FUNCTION_ID) {
						message = (String) in.readObject();
						for (int i = 0; i < groupWindowList.size(); i++) {
							if (groupWindowList.get(i).getId() == chatID) {
								groupWindowList.get(i).putMessage(message);
							}
						}
					} else if (functionID == START_CHAT_FUNCTION_ID) {
						userList = (ArrayList<User>) in.readObject();
						addChat(userList, chatID);
					} else if (functionID == SEND_MESSAGE_FUNCTION_ID) {
						message = (String) in.readObject();
						System.out.println(message);
						System.out.println(chatID);
						for (int i = 0; i < chatWindowList.size(); i++) {
							if (chatWindowList.get(i).getId() == chatID) {
								chatWindowList.get(i).putMessage(message);
							}
						}
					} else if (functionID == REMOVE_FROM_CHAT_FUNCTION_ID) {
						userFromChat = (User) in.readObject();
						for (int i = 0; i < chatWindowList.size(); i++) {
							if (chatWindowList.get(i).getId() == chatID) {
								chatWindowList.get(i).getUserList()
										.remove(userFromChat);
							}
						}
						chatMemPanel.removeContact(userFromChat);
					} else if (functionID == F.SAVE_STICKY_NOTE) {
						System.out.println("Sticky Note recieved");
						System.out.println("For group: " + chatID);
						message = (String) in.readObject();
						System.out
								.println("Sticky Note message is: " + message);
						if(getStickyNoteWithId(chatID)!= null)
							getStickyNoteWithId(chatID).putMessage(message);
					}

					System.out.println("Current chatID: " + chatID);
					System.out.println("Vi har gått igenom tråden.");
					incomingChat.close();
					socket.close();
					in.close();

				} catch (IOException e1) {
					e1.printStackTrace();
				} catch (ClassNotFoundException e) {
					e.printStackTrace();
				}
			}
		}
	};

	public void updateOnlineStatus(User user) {
		kontakt.updateOnlineStatus(user);
	}

	public void addToGroup(Group group) {
		this.group.addGroup(group);
	}

	public void removeFromGroup(Group group) {
		this.group.removeGroup(group);
	}

	public void updateGroup(Group group) {
		this.group.updateGroup(group);
	}

	private void setChatLayout(JPanel chatPanel, JTabbedPane chatPane,
			ChatMemberPanel chatMemberPanel, GroupLayout chatPanelLayout) {

		chatPanel.setLayout(chatPanelLayout);
		chatPanelLayout.setHorizontalGroup(chatPanelLayout
				.createSequentialGroup()
				.addComponent(chatMemberPanel, GroupLayout.PREFERRED_SIZE,
						GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
				.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
				.addComponent(chatPane));
		chatPanelLayout.setVerticalGroup(chatPanelLayout
				.createParallelGroup(GroupLayout.Alignment.LEADING)
				.addComponent(chatMemberPanel, GroupLayout.DEFAULT_SIZE,
						GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)

				.addComponent(chatPane));
	}

}
